package com.qingxin.sys.verifier.rules;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import com.qingxin.sys.verifier.FormMap;
import com.qingxin.sys.verifier.VerifyMsg;
import com.qingxin.sys.verifier.VerifyRule;

/**
 * 请求参数验证
 * @author Administrator
 *
 */
public class RequestRule extends VerifyRule {
	
	private String scope;		//验证范围：request/session/header/cookie
	private String name;		//参数名
	private String type;		//eq等于、in包含、reg正则匹配
	private String dataType;	//数据类型：number/string，当type=reg时仅string，默认string
	private String compare;		//and/or，仅type=reg时有效
	private boolean empty;		//允许空值，默认不允许
	private boolean notnull;
	private boolean ignoreCase;
	private String value;
	private List<String> values;//常量值或正则表达式	
	
	
	public RequestRule() {
		this.type =  "eq";
		this.dataType = "string";
		this.compare = "or";
		this.empty = false;
		this.notnull = true;
		this.ignoreCase = true;
		this.values = new ArrayList<String>();
	}
	
	
	@Override
	public boolean isValid(String name, String label, FormMap formMap) {
		if(values.size() == 0){
			return true;
		}
		name = this.name;//使用配置name
		label = null;
		String value = null;
		HttpServletRequest request = formMap.getRequest();
		if(request != null){
			if("header".equalsIgnoreCase(scope)){
				value = request.getHeader(name);
			}else if("cookie".equalsIgnoreCase(scope)){
				Cookie[] cookies = request.getCookies();
				if(cookies != null){
					for(Cookie c : cookies){
						if(c.getName().equals(name)) {
							value = c.getValue();
							break;
						}
					}//for
				}
			}else if("session".equalsIgnoreCase(scope)){
				HttpSession session = request.getSession(false);
				if(session != null && session.getAttribute(name) != null){
					value = session.getAttribute(name).toString();
				}
			}else if("request".equalsIgnoreCase(scope)){
				value = formMap.getParameter(name);
			}
		}
		if(notnull && value == null){
			message = createMessage(null, "{scope}", scope, "name", name);
			if(message == null){
				message = scope+"["+name+"]值不能为null";
			}
			return false;
		}
		if(empty && isEmpty(value)){
			return true;
		}
		if(value == null){
			value = "";
		}
		boolean all = "and".equalsIgnoreCase(compare);
		boolean pass = false;
		if("eq".equalsIgnoreCase(type)){
			for(String v1 : values){
				boolean valid = false;
				if("number".equalsIgnoreCase(dataType)){
					try {
						valid = (new BigDecimal(v1)).equals(new BigDecimal(value));
					} catch (Exception e) {
						e.printStackTrace();
					}
				}else{
					if(ignoreCase){
						valid = v1.equalsIgnoreCase(value);
					}else{
						valid = v1.equals(value);
					}
				}
				if(valid){
					pass = true;
					break;
				}
			}
		}else if("in".equalsIgnoreCase(type)){
			for(String v1 : values){
				boolean valid = false;
				if(ignoreCase){
					valid = value.toLowerCase().indexOf(v1.toLowerCase()) != -1;
				}else{
					valid = value.indexOf(v1) != -1;
				}
				if(!all && valid){
					pass = true;
					break;
				}
				if(all && !valid){
					break;
				}
			}
		}else if("reg".equalsIgnoreCase(type)){
			for(String reg : values){
				boolean valid = false;
				try {
					valid = Pattern.compile(reg, ignoreCase ? Pattern.CASE_INSENSITIVE : 0).matcher(value).matches();
				} catch (Exception e) {
					e.printStackTrace();
				}
				if(!all && valid){
					pass = true;
					break;
				}
				if(all && !valid){
					break;
				}
			}
		}
		
		if(!pass){
			message = createMessage(null, "{scope}", scope, "name", name);
			if(message == null){
				message = scope+"["+name+"]值无效";
			}
		}
		
		return pass;
	}
	
	
	@Override
	public Map<String, Object> getRuleCfg(String name, String label) {
		return null;//该类型不进行前台验证
	}
	
	
	@Override
	public VerifyMsg getMessage(String id, String name, String label) {
		return super.getMessage(this.name, this.name, scope+"["+this.name+"]");
	}
	
	
	@Override
	protected void handleRuleArg(String arg) {
		super.handleRuleArg(arg);
		if("a".equals(arg)){
			setCompare("and");
		}else if("o".equals(arg)){
			setCompare("or");
		}else if("I".equals(arg)){
			setIgnoreCase(false);
		}else if("i".equals(arg)){
			setIgnoreCase(true);
		}else if("s".equals(arg)){
			setDataType("string");
		}else if("n".equals(arg)){
			setDataType("number");
		}else if("_eq_".equals(arg)){
			setType("eq");
		}else if("_in_".equals(arg)){
			setType("in");
		}else if("_reg_".equals(arg)){
			setType("reg");
		}else if("_empty_".equals(arg)){
			setEmpty(true);
		}else if("_null_".equals(arg)){
			setNotnull(false);
		}
	}
	
	
	
	public String getScope() {
		return scope;
	}
	public void setScope(String scope) {
		this.scope = scope;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getType() {
		return type;
	}
	public void setType(String type) {
		this.type = type;
	}
	public String getDataType() {
		return dataType;
	}
	public void setDataType(String dataType) {
		this.dataType = dataType;
	}
	public String getCompare() {
		return compare;
	}
	public void setCompare(String compare) {
		this.compare = compare;
	}
	public boolean isEmpty() {
		return empty;
	}
	public void setEmpty(boolean empty) {
		this.empty = empty;
	}
	public boolean isNotnull() {
		return notnull;
	}
	public void setNotnull(boolean notnull) {
		this.notnull = notnull;
	}
	public boolean isIgnoreCase() {
		return ignoreCase;
	}
	public void setIgnoreCase(boolean ignoreCase) {
		this.ignoreCase = ignoreCase;
	}
	public String getValue() {
		return value;
	}
	public void setValue(String value) {
		this.value = value;
		values.add(value);
	}
	public List<String> getValues() {
		return values;
	}
	public void setValues(List<String> values) {
		this.values = values;
	}
	public void addValue(String value){
		values.add(value);
	}


	@Override
	public void setForeground(boolean foreground) {
		super.setForeground(false);
	}
	
}
